﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class NativeAOT
{
    [UnmanagedCallersOnly(EntryPoint = "nmtc")]
    public static unsafe void nmtc(IntPtr x_ptr, int n, double b, int m, double eps, IntPtr f_xa_n_ptr)
    {
        double* x = (double*)x_ptr.ToPointer();
        f_xa_n = Marshal.GetDelegateForFunctionPointer<delegatefunc_xa_n>(f_xa_n_ptr);

        nmtc(x, n, b, m, eps);
    }

    /// <summary>
    /// 蒙特卡罗法求解非线性方程组
    /// f(double[] x, int n)计算方程组模函数值的函数名。
    /// </summary>
    /// <param name="x">x[n]存放实数解初值。</param>
    /// <param name="n">方程组阶数</param>
    /// <param name="b">均匀分布随机数的端点初值。</param>
    /// <param name="m">控制调节b的参数。</param>
    /// <param name="eps">控制精度要求。</param>
    /// <param name="inter">若程序显示“b调整了100次！迭代不收敛！”，则需调整b和m的值再试。</param>
    public static unsafe void nmtc(double* x, int n, double b, int m, double eps, int inter = 100)
    {
        int k, i, flag;
        double z = 0.0, z1;
        double* y = stackalloc double[n];

        k = 0;
        flag = 0;
        z = f_xa_n(x, n);
        while (flag <= inter)
        {
            k = k + 1;
            //产生一组随机数
            for (i = 0; i <= n - 1; i++)
            {
                y[i] = -b + 2.0 * b * (rnd.NextDouble()) + x[i];
            }
            z1 = f_xa_n(y, n);
            if (z1 >= z)
            {
                if (k == m)
                {
                    flag = flag + 1;
                    k = 0;
                    b = b / 2.0;
                }
            }
            else
            {
                k = 0;
                for (i = 0; i <= n - 1; i++)
                {
                    x[i] = y[i];
                }
                z = z1;
                if (z < eps)
                {
                    return;
                }
            }
        }
        return;
    }

    /*
    // 蒙特卡罗法求解非线性方程组例
      int main()
      { 
          int i,n,m;
          double nmtcf(double [],int);
          double b,eps,x[3]={0.0,0.0,0.0};
          b=2.0; m=50; n=3; eps=0.000001;
          nmtc(x,n,b,m,eps,nmtcf);
          for (i=0; i<=2; i++)  
              cout <<"x(" <<i <<") = " <<x[i] <<endl;
          cout <<"验证: |F| = " <<nmtcf(x,n) <<endl;
          return 0;
      }
    // 计算方程组模
      double nmtcf(double x[], int n)
      { 
          double f,f1,f2,f3;
          n=n;
          f1=3.0*x[0]+x[1]+2.0*x[2]*x[2]-3.0;
          f2=-3.0*x[0]+5.0*x[1]*x[1]+2.0*x[0]*x[2]-1.0;
          f3=25.0*x[0]*x[1]+20.0*x[2]+12.0;
          f=sqrt(f1*f1+f2*f2+f3*f3);
          return(f);
      }
    */
}

